﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace Editor
{
    // 用来替换的文本
    public class AutoBuildTemplate
    {
        public static string UIClass =
            @"
#类名#

#成员#	

#查找#
";
    }
    
    // 用来替换的文本
    public class AutoBuildTemplateCtrl
    {
        public static string UIClass =
            @"
using ZYLFramework.Manage;
using ZYLFramework.UI;

namespace Game.UI
{
    public class #类名#Ctrl:UICtrl
    {
        public #类名#View View;
        public #类名#Model Model;
        public override void Init()
        {
            View = BaseView as #类名#View;
            Model = BaseModel as #类名#Model;
        }
    }
}
";
    }
    
    // 用来替换的文本
    public class AutoBuildTemplateModel
    {
        public static string UIClass =
            @"
using ZYLFramework.UI;

namespace Game.UI
{
    public class #类名#Model:UIModel
    {
    }
}
";
    }
    
    // 用来替换的文本
    public class AutoBuildTemplateView
    {
        public static string UIClass =
            @"
using UnityEngine;
using UnityEngine.UI;
using ZYLFramework.UI;

namespace Game.UI
{
    public class #类名#View:UIView
    {
        #成员#	

        public override void Init()
        {
            #查找#
        }
    }
}
";
    }
    
    // UI配置
    public class UIConfig
    {
        public Dictionary<string, string> dicUIType;
        public Dictionary<string, int> dicUIWeight;

        public UIConfig()
        {
            dicUIType = new Dictionary<string, string>();

            //通过命名来映射类型
            dicUIType.Add("Image", "Image");
            dicUIType.Add("Button", "Btn");
            dicUIType.Add("ScrollRect", "ScrollRect");
            dicUIType.Add("Text", "Text");
            dicUIType.Add("GridLayoutGroup", "GridLayoutGroup");
            dicUIType.Add("PassAndOut", "PassAndOut");
            dicUIType.Add("RectTransform", "Rect"); 
            dicUIType.Add("Slider", "Slider"); 
            
            dicUIWeight = new Dictionary<string, int>();

            //通过命名来映射类型
            dicUIWeight.Add("Image", 10);
            dicUIWeight.Add("Button", 30);
            dicUIWeight.Add("ScrollRect",33);
            dicUIWeight.Add("Slider",34);
            dicUIWeight.Add("Text", 20);
            dicUIWeight.Add("GridLayoutGroup",32);
            dicUIWeight.Add("PassAndOut",31);
            dicUIWeight.Add("RectTransform", 0);
        }
    }

    public class AutoBuild
    {
        public AutoBuild()
        {
        }

        // 扩展的右键菜单，在Assets目录下的对象右键会有My Tool这个选项，里面会有CreateUICode这个子选项
        [MenuItem("Assets/My Tool/CreateUICode")]
        public static void CreateUICode()
        {
            

            var dicUIType = new Dictionary<string, string>();

            //通过命名来映射类型
            dicUIType.Add("Image", "Image");
            dicUIType.Add("Button", "Btn");
            dicUIType.Add("ScrollRect", "ScrollRect");
            dicUIType.Add("Text", "Text");
            dicUIType.Add("GridLayoutGroup", "GridLayoutGroup");
            dicUIType.Add("PassAndOut", "PassAndOut");
            dicUIType.Add("RectTransform", "Rect");
       
            var dicUIWeight = new Dictionary<string, int>();

            //通过命名来映射类型
            dicUIWeight.Add("Image", 10);
            dicUIWeight.Add("Button", 30);
            dicUIWeight.Add("ScrollRect",33);
            dicUIWeight.Add("Text", 20);
            dicUIWeight.Add("GridLayoutGroup",32);
            dicUIWeight.Add("PassAndOut",31);
            dicUIWeight.Add("RectTransform", 0);


            //获取选择的对象
            GameObject[] selectobjs = Selection.gameObjects;

            //可以多选，所以返回的数组
            foreach (GameObject go in selectobjs)
            {
                //选择的物体
                GameObject selectobj = go.transform.root.gameObject;

                //物体的子物体
                Transform[] _transforms = selectobj.GetComponentsInChildren<Transform>(true);

                List<Transform> childList = new List<Transform>(_transforms);

                //UI需要查询的物体
                var mainNode = from trans in childList where trans.gameObject.CompareTag("BeFound") select trans;

                var nodePathList = new Dictionary<string, string>();

                //循环得到物体路径
                foreach (Transform node in mainNode)
                {
                    Transform tempNode = node;
                    string nodePath = "/"+tempNode.name;

                    // 如果是自己
                    if (tempNode.name.Equals(selectobj.name))
                    {
                        nodePath = "";
                    }
                    else
                    {
                        while (tempNode.parent && tempNode.parent != tempNode.root)
                        {
                            tempNode = tempNode.parent;
                            int index = nodePath.IndexOf('/');
                            nodePath = nodePath.Insert(index, "/" + tempNode.name);
                        }
                        // 去除最前面的 /
                        nodePath = nodePath.Substring(1);
                    }
                    nodePathList.Add(node.name, nodePath);
                }

                //成员变量字符串
                string memberstring = "";
                //查询代码字符串
                string loadedcontant = "";

                loadedcontant += "var go = Panel.gameObject;\r\n\t\t";
                //生成子物体代码
                foreach (Transform itemtran in mainNode)
                {
                    string itemName;
                    string weightName = "";
                    int weight = -1;
                    //详细到所有组件 进行优先级判断，优先级高的组件作为默认写入的组件
                    foreach (var sComponent in itemtran.transform.GetComponents<Component>())
                    {
                   
                        var splitList = sComponent.GetType().ToString().Split('.');
                        var typeName = splitList[splitList.Length - 1];
                        if (dicUIType.ContainsKey(typeName) && dicUIWeight[typeName] > weight)
                        {
                            weight = dicUIWeight[typeName];
                            weightName = typeName;
                        }
                    }

                    // 如果没有组件满足优先级
                    if (weight == -1)
                    {
                        weightName = "RectTransform";
                    }
               
                    // itemName = itemtran.name.Substring(0, 1).ToLower()+itemtran.name.Substring(1);
                    itemName = itemtran.name;
                    if (dicUIType.ContainsKey(weightName))
                    {
                        memberstring += "public " + weightName + " " + itemName + ";\r\n\t";
                        loadedcontant += itemName + " = " + "go.transform.Find(\"" + nodePathList[itemtran.name] + "\").GetComponent<" + weightName + ">();\r\n\t\t";
                    }
                }

                // 替换
                string classStr = "";
                classStr = AutoBuildTemplate.UIClass;
                classStr = classStr.Replace("#类名#", selectobj.name);
                classStr = classStr.Replace("#查找#", loadedcontant);
                classStr = classStr.Replace("#成员#", memberstring);

                Debug.Log("创建脚本" + selectobj.name + "成功!");
                // 输出,也可以写到文件里
                Debug.Log(classStr);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
        
        // 扩展的右键菜单，在Assets目录下的对象右键会有My Tool这个选项，CreateUIMVCCode
        [MenuItem("Assets/My Tool/CreateUIMVCCode")]
        public static void CreateUIMVCCode()
        {
            var uiConfig = new UIConfig();
            //获取选择的对象
            GameObject[] selectobjs = Selection.gameObjects;

            var go = selectobjs[0];
            //选择的物体
            GameObject selectobj = go.transform.root.gameObject;

            //物体的子物体
            Transform[] _transforms = selectobj.GetComponentsInChildren<Transform>(true);

            List<Transform> childList = new List<Transform>(_transforms);

            //UI需要查询的物体
            var mainNode = from trans in childList where trans.gameObject.CompareTag("BeFound") select trans;

            var nodePathList = new Dictionary<string, string>();

            //循环得到物体路径
            foreach (Transform node in mainNode)
            {
                Transform tempNode = node;
                string nodePath = "/"+tempNode.name;

                // 如果是自己
                if (tempNode.name.Equals(selectobj.name))
                {
                    nodePath = "";
                }
                else
                {
                    while (tempNode.parent && tempNode.parent != tempNode.root)
                    {
                        tempNode = tempNode.parent;
                        int index = nodePath.IndexOf('/');
                        nodePath = nodePath.Insert(index, "/" + tempNode.name);
                    }
                    // 去除最前面的 /
                    nodePath = nodePath.Substring(1);
                }
                nodePathList.Add(node.name, nodePath);
            }

            //成员变量字符串
            string memberstring = "";
            //查询代码字符串
            string loadedcontant = "";

            loadedcontant += "var go = Panel.gameObject;\r\n\t\t\t";
            //生成子物体代码
            foreach (Transform itemtran in mainNode)
            {
                string itemName;
                string weightName = "";
                int weight = -1;
                //详细到所有组件 进行优先级判断，优先级高的组件作为默认写入的组件
                foreach (var sComponent in itemtran.transform.GetComponents<Component>())
                {
               
                    var splitList = sComponent.GetType().ToString().Split('.');
                    var typeName = splitList[splitList.Length - 1];
                    if (uiConfig.dicUIType.ContainsKey(typeName) && uiConfig.dicUIWeight[typeName] > weight)
                    {
                        weight = uiConfig.dicUIWeight[typeName];
                        weightName = typeName;
                    }
                }

                // 如果没有组件满足优先级
                if (weight == -1)
                {
                    weightName = "RectTransform";
                }
           
                // itemName = itemtran.name.Substring(0, 1).ToLower()+itemtran.name.Substring(1);
                itemName = itemtran.name;
                if (uiConfig.dicUIType.ContainsKey(weightName))
                {
                    memberstring += "public " + weightName + " " + itemName + ";\r\n\t\t";
                    loadedcontant += itemName + " = " + "go.transform.Find(\"" + nodePathList[itemtran.name] + "\").GetComponent<" + weightName + ">();\r\n\t\t\t";
                }
            }
            
            string directoryPath = Application.dataPath + "/Script/Game/UI/" + selectobj.name;
            if (Directory.Exists(directoryPath) == false)   
            {
                Directory.CreateDirectory(directoryPath);   //只有当文件不存在的话，创建新文件
            }
            Debug.Log(directoryPath);

            // 写入View
            string classStr = "";
            string scriptPath = directoryPath+"/"+selectobj.name + "View.cs";
            classStr = AutoBuildTemplateView.UIClass;
            classStr = classStr.Replace("#类名#", selectobj.name);
            classStr = classStr.Replace("#查找#", loadedcontant);
            classStr = classStr.Replace("#成员#", memberstring);
            
            FileStream file = new FileStream(scriptPath, FileMode.CreateNew);
            StreamWriter fileW = new StreamWriter(file, System.Text.Encoding.UTF8);
            fileW.Write(classStr);
            fileW.Flush();
            fileW.Close();
            file.Close();

            // 写入Ctrl
            classStr = "";
            scriptPath = directoryPath+"/"+selectobj.name + "Ctrl.cs";
            classStr = AutoBuildTemplateCtrl.UIClass;
            classStr = classStr.Replace("#类名#", selectobj.name);
            
            file = new FileStream(scriptPath, FileMode.CreateNew);
            fileW = new StreamWriter(file, System.Text.Encoding.UTF8);
            fileW.Write(classStr);
            fileW.Flush();
            fileW.Close();
            file.Close(); 
            
            // 写入Model
            classStr = "";
            scriptPath = directoryPath+"/"+selectobj.name + "Model.cs";
            classStr = AutoBuildTemplateModel.UIClass;
            classStr = classStr.Replace("#类名#", selectobj.name);
            
            file = new FileStream(scriptPath, FileMode.CreateNew);
            fileW = new StreamWriter(file, System.Text.Encoding.UTF8);
            fileW.Write(classStr);
            fileW.Flush();
            fileW.Close();
            file.Close(); 
            
            Debug.Log("创建脚本 " + Application.dataPath + "/Script/Game/UI/" + selectobj.name + " 成功!");
            Debug.Log($"_uiManage.Register(UIEnum.{selectobj.name},\"{selectobj.name}\",new {selectobj.name}Ctrl(),new {selectobj.name}Model(),new {selectobj.name}View()); ");
            
            // 输出,也可以写到文件里
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }
}